home *** CD-ROM | disk | FTP | other *** search
- PROGRAM pcmfat;
- {*******************************************************************************
- * *
- * PCMFAT 1.1 Copyright (c) 1991 Barry Simon *
- * all rights reserved *
- * *
- * First Published in PC Magazine, September 10, 1991 *
- * *
- * Requires Turbo Pascal 6.0 to compile (because of use of inline assembler) *
- * *
- *******************************************************************************}
- {$A-}
- {the directive $A- needed StartCluster to line up}
- USES DOS, common;
-
- VAR
- dta : RECORD
- rawdrive : Byte;
- unused : ARRAY[0..25] OF Byte; {standard DTA starts at 0}
- StartCluster : Word; {to work require $A- directive!}
- FSize : LongInt;
- END;
- FCluster : LongInt;
- infcb : ARRAY[0..36] OF Byte;
- regs : registers;
- s : STRING;
- fname : STRING[8];
- fext : STRING[3];
- i, j : Byte;
- NumFATSec, FirstFATSec, InMemSec, CurrentSec, NumCluster : Word;
- CurrentCluster, PriorCluster, RecSec, RecOff : Word;
- RecShift : Boolean; {determines if first byte is offset in 3 nibble fat}
- separator : Char;
- NumFrag : Byte;
-
- PROCEDURE SyntaxError;
- BEGIN
- WriteLn(' Proper syntax is:');
- WriteLn(' PCMFAT <filename>');
- WriteLn(' where <filename> is in the default drive and directory.');
- Halt;
- END;
-
- FUNCTION GetRec : Word;
- BEGIN
- IF Use3NibbleFAT THEN BEGIN
- IF RecShift THEN
- GetRec := (Word(Sector[RecOff]) DIV 16)+16*Word(Sector[RecOff+1])
- ELSE
- GetRec := Word(Sector[RecOff])+256*(Word(Sector[RecOff+1]) MOD 16);
- END ELSE
- GetRec := Word(Sector[RecOff])+256*Word(Sector[RecOff+1]);
- END;
-
- PROCEDURE GetLoc;
- BEGIN
- IF Use3NibbleFAT THEN BEGIN
- RecSec := 3*(CurrentCluster DIV 1024)+FirstFATSec;
- IF RecSec > NumFATSec THEN BEGIN
- WriteLn;
- WriteLn('FAT error. Please run chkdsk **without** /f. Program Halted.');
- Halt;
- END;
- RecOff := ((3*(CurrentCluster MOD 1024)) DIV 2);
- IF ((RecOff MOD 3) = 0) THEN RecShift := False ELSE RecShift := True;
- END ELSE BEGIN
- RecSec := Hi(CurrentCluster)+FirstFATSec;
- IF RecSec > NumFATSec THEN BEGIN
- WriteLn;
- WriteLn('FAT error. Please run chkdsk **without** /f. Program Halted.');
- Halt;
- END;
- RecOff := 2*Lo(CurrentCluster);
- END;
- END;
-
- PROCEDURE GetSector;
- BEGIN
- CurrentSec := RecSec;
- IF NOT(CurrentSec = InMemSec) THEN BEGIN
- ReadSector(CurrentSec);
- InMemSec := CurrentSec;
- END;
- END;
-
- BEGIN
- WriteLn('PC Magazine''s FAT Reader');
- WriteLn(' copyright, Barrry Simon 1991');
- IF ParamCount = 0 THEN SyntaxError;
- s := ParamStr(1);
- IF (pos('\', s)+pos(':', s)) > 0 THEN SyntaxError;
- i := pos('.', s);
- IF i = 0 THEN BEGIN
- s := s+'.';
- i := Length(s);
- END;
- IF i > 9 THEN SyntaxError;
- fname := Copy(s, 1, i-1);
- Delete(s, 1, i);
- IF Length(s) > 3 THEN SyntaxError;
- fext := s;
- FOR j := 1 TO Length(fname) DO fname[j] := Upcase(fname[j]);
- FOR j := 1 TO Length(fext) DO fext[j] := Upcase(fext[j]);
- s := fname+'.'+fext;
- FOR j := 1 TO (8-Length(fname)) DO fname := fname+' ';
- FOR j := 1 TO (3-Length(fext)) DO fext := fext+' ';
- FOR i := 1 TO 8 DO infcb[i] := Ord(fname[i]);
- FOR i := 9 TO 11 DO infcb[i] := Ord(fext[i-8]);
- infcb[0] := 0; {default drive}
- WITH regs DO BEGIN
- ah := $1A; {set DTA}
- ds := Seg(dta);
- dx := Ofs(dta);
- msdos(regs);
- ah := $11;
- dx := Ofs(infcb);
- ds := Seg(infcb);
- msdos(regs);
- IF al <> 0 THEN BEGIN
- WriteLn(' ', s, ' not found');
- SyntaxError;
- END;
- END;
- DriveNum := dta.rawdrive-1; {int 25 and service 11 differ on A=0 or 1, etc}
- ReadSector(0);
- IF (BootSector.BytesPerSector <> 512) THEN BEGIN
- WriteLn(' The sector size isn''t 512 bytes; program halted.');
- Halt;
- END;
- FCluster := ((dta.FSize-1) DIV (512*BootSector.SectorsPerCluster))+1;
- WriteLn(' The file ', s, ' has ', FCluster, ' clusters');
- WriteLn(' Starting Cluster is ',
- HexWord(dta.StartCluster), ' Hex (= ', dta.StartCluster, ' decimal)');
- {For display purposes, limit to files with no more than 256 clusters -
- that's 512K on a typical hard disk}
- IF (FCluster > 256) THEN BEGIN
- WriteLn(' This program will only report detailed allotment');
- WriteLn(' for files with fewer than 256 clusters. Program halted.');
- Halt;
- END;
- FirstFATSec := BootSector.SectorsBeforeData;
- NumFATSec := BootSector.NumSecPerFAT;
- asm
- mov ah, $1B
- push ds
- Int $21
- pop ds
- mov NumCluster, dx
- END;
- Use3NibbleFAT := (NumCluster < 4097);
- {Should read Partition table for totally accurate call}
- CurrentCluster := dta.StartCluster;
- InMemSec := 0;
- NumFrag := 1;
- Writeln (' The files occupies clusters (* indicates fragments):' );
- Write (' ' , HexWord(CurrentCluster));
- for i := 2 to FCluster do begin
- GetLoc;
- GetSector;
- PriorCluster := CurrentCluster;
- CurrentCluster := GetRec;
- If (CurrentCluster = (PriorCluster + 1)) then separator := ' ' else begin
- separator := '*';
- inc (NumFrag);
- end;
- Write (separator,HexWord (CurrentCluster));
- end;
- Writeln;
- Writeln;
- Writeln ('The file has ',NumFrag ,' fragments.');
- end.
-
-